package com.sce.core.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.expression.OAuth2MethodSecurityExpressionHandler;

import com.sce.core.service.UserService;

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{
	
	@Autowired
	private UserService userService;

//	@Autowired
//	private Settings settings;

	
	//配置匹配用户时密码规则
		public PasswordEncoder passwordEncoder() {
			//自适应所有密码规则
			return PasswordEncoderFactories.createDelegatingPasswordEncoder();
		}
		
		//配置全局设置
		@Autowired
		public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
			//设置UserDetailsService以及密码规则
	        auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
		}

		//排除/hello路径拦截
	    @Override
	    public void configure(WebSecurity web) throws Exception {
	    	web.ignoring().antMatchers("/hello","/mongodb");

//	    	web
//                .antMatchers("/v2/api-docs", "/configuration/ui", "/swagger-resources/**",
//                        "/configuration/security", "/swagger-ui.html", "/webjars/**").permitAll()
//                .anyRequest().authenticated()
//                .and()
//            .formLogin()
//                .loginPage("/login")
//                .permitAll()
//                .and()
//            .logout()
//                .permitAll();
	    }

		public void configure(HttpSecurity http) throws Exception {
			http
			// 由于使用的是oauth，我们这里不需要csrf
			//.csrf().disable()
			// 基于token，所以不需要session
			.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
			.and().authorizeRequests()
			//.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
			// 允许对于网站静态资源的无授权访问
            .antMatchers(
                    HttpMethod.GET,
                    "/",
                    "/*.html",
                    "/favicon.ico",
                    "/**/*.html",
                    "/**/*.css",
                    "/**/*.js"
            ).permitAll()
         // 对于获取token的rest api要允许匿名访问
            .antMatchers("/auth/**").permitAll()
            // 除上面外的所有请求全部需要鉴权认证
            .anyRequest().authenticated();

			 // 禁用缓存
			http.headers().cacheControl();
			
			/*http.authorizeRequests()
					.antMatchers("/v2/api-docs", "/configuration/ui", "/swagger-resources/**",
							"/configuration/security", "/swagger-ui.html", "/webjars/**").permitAll()
					.and().logout()
					.permitAll()
					.and()
					.formLogin()
					.permitAll().and()
					.authorizeRequests()
					.antMatchers("/hello/").permitAll()
					.antMatchers("/sayHello/**","/api/*").authenticated()
					.and().httpBasic();*/
		}


	    @Override
	    @Bean
	    public AuthenticationManager authenticationManagerBean() throws Exception {
	        return super.authenticationManagerBean();
	    }
	    
	    //开户全局方法拦截
	    @EnableGlobalMethodSecurity(prePostEnabled = true,jsr250Enabled = true)
	    public static class GlobalSecurityConfiguration extends GlobalMethodSecurityConfiguration {
	    	
	    	protected MethodSecurityExpressionHandler createExpressionHandler() {
	    		return new OAuth2MethodSecurityExpressionHandler();
	    	}
	    }
	    
	    public static void main(String[] args) {
			
	    	System.out.println(PasswordEncoderFactories.createDelegatingPasswordEncoder().encode("admin"));
		}
}
